/*
 * Author: vdaras
 */

#include "../sdl/Color.h"
#include "../sdl/Surface.h"
#include "Graphics.h"
#include <algorithm>
#ifdef DSDL_GFX_ENABLED
#include <SDL/SDL_gfxPrimitives.h>
#endif
namespace gfx
{

/**
 * Uses the Bresenham's line drawing algorithm. Don't ask for comments, I don't know what it does I just coded the
 * algorithm. See http://en.wikipedia.org/wiki/Bresenham's_line_algorithm for further explanation.
 *
 * @param target: the surface which the line will be drawn on
 * @param x0: x coordinate of the starting point
 * @param y0: y coordinate of the starting point
 * @param x1: x coordinate of the ending point
 * @param y1: y coordinate of the ending point
 * @param color: the color of the line
 * @param thickness: thickness of the line (NOT implemented yet)
 */

void drawLine(sdl::Surface *target, int x0, int y0, int x1, int y1, const sdl::Color &color, float thickness)
{
#if !defined DSDL_GFX_ENABLED
    int deltaX, deltaY, error, ystep;
    int x, y;

    bool steep = abs(y1 - y0) > abs(x1 - x0);
    if(steep)
    {
        std::swap(x0, y0);
        std::swap(x1, y1);
    }

    if(x0 > x1)
    {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }

    deltaX = x1 - x0;
    deltaY = abs(y1 - y0);
    error = deltaX / 2;
    y = y0;

    if(y0 < y1)
    {
        ystep = 1;
    }
    else
    {
        ystep = -1;
    }

    for(x = x0; x <= x1; ++x)
    {
        if(steep)
        {
            target->SetPixel(y, x, color);
        }
        else
        {
            target->SetPixel(x, y, color);
        }

        error = error - deltaY;

        if(error < 0)
        {
            y += ystep;
            error = error + deltaX;
        }
    }
#else
    lineRGBA(target->GetBuffer(), x0, y0, x1, y1, color.GetR(), color.GetG(), color.GetB(), 255);
#endif
}


/**
 * This routine draws a non-filled rectangle on the target surface.
 *
 * @param
 * @paramtarget: the target surface
 * @param upperX: the x coo     rdinate of the rectangle's upper left corner
 * @param upperY: the y coordinate of the rectangle's upper left corner
 * @param width: width of the rectangle
 * @param height: height of the rectangle
 * @param color: color of the rectangle
 */

void drawRect(sdl::Surface *target, int upperX, int upperY, int width, int height, const sdl::Color &color)
{
    if(upperX < 0 || upperY < 0 || upperX + width > target->GetWidth() || upperY + height > target->GetHeight())
        return;

#if !defined DSDL_GFX_ENABLED
    drawLine(target, upperX, upperY, upperX + width, upperY, color);
    drawLine(target, upperX, upperY, upperX, upperY + height, color);
    drawLine(target, upperX + width, upperY, upperX + width, upperY + height, color);
    drawLine(target, upperX, upperY + height, upperX + width, upperY + height, color);
#else
    rectangleRGBA(target->GetBuffer(), upperX, upperY, upperX + width, upperY + height, color.GetR(), color.GetG(), color.GetB(), 255);
#endif
}

};

